package cn.wsalix.weixin.util;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.io.IOUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;

import cn.wsalix.code.JsonMapper;
import cn.wsalix.constant.WxGlobal;
import cn.wsalix.weixin.entity.WxAccessToken;
import cn.wsalix.weixin.entity.WxConfig;
import cn.wsalix.weixin.entity.WxMenu;
import cn.wsalix.weixin.entity.WxMessage;
import cn.wsalix.weixin.mp.ase.AesException;
import cn.wsalix.weixin.mp.ase.WXBizMsgCrypt;

import com.thoughtworks.xstream.XStream;

public class WxUtils {
	public Map<String, Object> buildMap(String fromXML) {
		Document doc;
		try {
			doc = DocumentHelper.parseText(fromXML);
			Map<String, Object> map = XmlUtils.Dom2Map(doc);
			return map;
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;

	}

	public String buildXml(HttpServletRequest request, String token,
			String appId, String aesKey) {
		InputStream inputStream = null;
		try {
			inputStream = request.getInputStream();
			String fromXML = IOUtils.toString(inputStream);
			String msgSignature = request.getParameter("msg_signature");
			String timeStamp = request.getParameter("timestamp");
			String nonce = request.getParameter("nonce");
			WXBizMsgCrypt pc = new WXBizMsgCrypt(token, aesKey, appId);
			String result = pc.decryptMsg(msgSignature, timeStamp, nonce,
					fromXML);
			return result;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (AesException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return "";
	}

	public String reciveXml(String fromXML, String token, String appId,
			String aesKey, String msgSignature, String timeStamp, String nonce) {
		try {
			// String fromXML = IOUtils.toString(inputStream);
			WXBizMsgCrypt pc = new WXBizMsgCrypt(token, aesKey, appId);
			String result = pc.decryptMsg(msgSignature, timeStamp, nonce,
					fromXML);
			return result;
		} catch (AesException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return "";
	}

	private XStream xStream;

	public WxUtils() {
		if (this.xStream == null) {
			this.xStream = new XStream();
		}
	}

	@SuppressWarnings("unchecked")
	public <T> Result<T> parse(String xmlData, Class<T> clazz) {
		Result<T> result = new Result<T>();
		this.xStream.alias("xml", clazz);
		xStream.autodetectAnnotations(true);
		T obj = (T) this.xStream.fromXML(xmlData);

		result.setResult(obj);
		result.setSuccess(true);
		return result;
	}

	public String reciveXml(String string, String token, String appId,
			String aesKey, WxMessage wxMessage) {
		try {
			// String fromXML = IOUtils.toString(inputStream);
			WXBizMsgCrypt pc = new WXBizMsgCrypt(token, aesKey, appId);
			String result = pc.decryptMsg(wxMessage.getMsgSignature(),
					wxMessage.getTimestamp(), wxMessage.getNonce(),
					wxMessage.getXmlContent());
			return result;
		} catch (AesException e) {
			e.printStackTrace();
		}
		return "";
	}

	public String createMenu(WxConfig wxConfig, List<WxMenu> menus) {
		WxAccessToken accessToken = fetchAccessToken(wxConfig);
		if (accessToken.getAccess_token() == null) {
			return "fetch access_token error";
		}
		String createMenuUrl = WxGlobal.doGetMenuCreate(accessToken.getAccess_token());
		return sendPost(createMenuUrl, JsonMapper.toJson(menus));
	}

	private static WxAccessToken fetchAccessToken(WxConfig wxConfig) {
		String getAccessTokenUrl = WxGlobal.doGetAccessToken(wxConfig.getAppId(), wxConfig.getAsekey());
		String accessTokenStr = HttpUtil.httpsGet(getAccessTokenUrl);
		WxAccessToken wxAccessToken = JsonMapper.fromJson(accessTokenStr,
				WxAccessToken.class);
		return wxAccessToken;
	}

	private String sendPost(String url, String body){
		return "";
	}
}
